<?php

namespace App\Services;
use Hyperf\Guzzle\HandlerStackFactory;
use Hyperf\Guzzle\CoroutineHandler;
use Hyperf\Utils\ApplicationContext;
use GuzzleHttp\Client;


class Wechat
{
    /**根据code获取token和openid
     * @param $code
     * @return array
     * @throws \Exception
     */
    public static function getOpenId($code, $token)
    {
        $uri = 'https://api.weixin.qq.com/wxa/getpluginopenpid?access_token=' . $token;
        $data = [
            'code' => $code
        ];
        $response = self::curlPost($uri,$data);
        return $response;
    }

    /**获取手机号
     * @param string $token
     * @param string $openId
     * @param string $code
     * @return mixed
     * @throws \Exception
     */
    public static function getPhoneNumber(string $token, string $code)
    {
        $uri = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $token;
        $data = [
            'code' => $code
        ];
        $rt = self::curlPost($uri,$data);
        $rt = json_decode($rt, true);
        return $rt;
    }
    /**获取token
     * @return false|mixed|\Redis|string
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    //获取小程序access_token
    public static function getAccessToken()
    {

        $appid = config('wxpay.appid');
        $secret = config('wxpay.appsecret');
        if(redis()->exists('access_token_applets')){
            return redis()->get('access_token_applets');
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/stable_token';
        $data = [
            'grant_type' => 'client_credential',
            'appid' => $appid,
            'secret' => $secret
        ];
        $rt = self::httpPostRequest($url, $data);
        $rt = json_decode($rt, true);
        if (!isset($rt['access_token'])) {
            return '';
        }
        redis()->setex('access_token_applets', 7200, $rt['access_token']);
        return $rt['access_token'];

    }

    public static function getMpToken()
    {

        $appid = config('wxpay.mpid');
        $secret = config('wxpay.mpsecret');
        if(redis()->exists('access_token_applets_mp')){
            return redis()->get('access_token_applets_mp');
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/stable_token';
        $data = [
            'grant_type' => 'client_credential',
            'appid' => $appid,
            'secret' => $secret
        ];
        $rt = self::httpPostRequest($url, $data);
        $rt = json_decode($rt, true);
        if (!isset($rt['access_token'])) {
            return '';
        }
        redis()->setex('access_token_applets_mp', 7200, $rt['access_token']);
        return $rt['access_token'];

    }

    /**生成URL LINK
     * @param $path
     * @param $query
     * @return bool|string
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public static function getUrlLink($path = '/pages/index/index', $query = '')
    {
        $asscess_token = static::getAccessToken();
        $url = 'https://api.weixin.qq.com/wxa/generate_urllink';
        $data = [
            'path' => $path,
            'query' => $query
        ];
        $common_parameters = [
            'access_token' => $asscess_token
        ];
        $rt = self::httpPostRequest($url, $data, $common_parameters);
        return $rt;
    }

    /**生成二维码
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public static function createQrCode(): array
    {
        $asscess_token = static::getAccessToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create';
        $common_parameters = [
            'access_token' => $asscess_token
        ];
        $uuid = uniqid();
        $data = [
            'expire_seconds' => 60,
            'action_name' => 'QR_STR_SCENE',
            'action_info' => ['scene' => ['scene_str' => $uuid]]
        ];
        $rt = self::httpPostRequest($url, $data, $common_parameters);
        $rt = json_decode($rt, true);
        if (array_key_exists('errcode', $rt) && $rt['errcode'] == 40001) {
            redis()->del('access_token_applets');
            self::getAccessToken();
        }
        $rt = self::httpPostRequest($url, $data, $common_parameters);
        $rt = json_decode($rt, true);
        $rt['qr_code_url'] = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $rt['ticket'];
        $rt['uuid'] = $uuid;
        return $rt;

    }

    /**curl
     * @param $url
     * @param $data
     * @return string
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public static function curlPost($url, $data,$type = 'body')
    {
        $container = ApplicationContext::getContainer();
        $handlerStackFactory = $container->get(HandlerStackFactory::class);
        $handlerStack = $handlerStackFactory->create();
        $client = new Client(['handler' => new CoroutineHandler($handlerStack)]);
        if($type == 'body'){
            $data = json_encode($data);
        }
        $response = $client->post($url, [
            'headers' => [
                'Content-Type' => 'application/json',
            ],
            $type=>$data
        ]);

        return $response->getBody()->getContents();
    }

    public static function curlGet($url,$data=[]){
        $container = ApplicationContext::getContainer();
        $handlerStackFactory = $container->get(HandlerStackFactory::class);
        $handlerStack = $handlerStackFactory->create();
        $client = new Client(['handler' => new CoroutineHandler($handlerStack)]);
        $response = $client->get($url, [
            'headers' => [
                'Content-Type' => 'application/json',
            ],
            'query'=>$data
        ]);

        return $response->getBody()->getContents();
    }

//    public static function curlPost($url, $data)
//    {
//        $curl = curl_init();
//        curl_setopt_array($curl,
//            array(CURLOPT_URL => $url,
//                CURLOPT_RETURNTRANSFER => true,
//                CURLOPT_ENCODING => '',
//                CURLOPT_MAXREDIRS => 10,
//                CURLOPT_TIMEOUT => 0,
//                CURLOPT_FOLLOWLOCATION => true,
//                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
//                CURLOPT_CUSTOMREQUEST => 'POST',
//                CURLOPT_POSTFIELDS => json_encode($data),
//                CURLOPT_HTTPHEADER => array( 'Content-Type: application/json')));
//        $response = curl_exec($curl);
//        curl_close($curl);
//        return $response;
//    }

    /**微信curl
     * @param $url
     * @param $parameters
     * @param $common_parameters
     * @return bool|string
     * @throws \Exception
     */
    public static function httpPostRequest($url = '', $parameters = [], $common_parameters = [])
    {


        $parameters = json_encode($parameters);
        $request_url = $url . '?' . http_build_query($common_parameters);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $request_url);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $parameters);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            "Content-Type:application/json"
        ));
        $response = curl_exec($curl);
        if (curl_error($curl)) {
            $error_msg = curl_error($curl);
            $error_no = curl_errno($curl);
            curl_close($curl);
            throw new \Exception($error_msg, $error_no);
        }
        curl_close($curl);
        return $response;

    }

    /**
     * curl post json 请求
     * */
    public static function postCurl($url, $data, $json = false)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (!empty($data)) {
            if ($json && is_array($data)) {
                $data = json_encode($data);
            }
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            if ($json) { //发送JSON数据
                curl_setopt($curl, CURLOPT_HEADER, 0);
                curl_setopt($curl, CURLOPT_HTTPHEADER,
                    array('Content-Type: application/json; charset=utf-8', 'Content-Length:' . strlen($data)));
            }
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $res = curl_exec($curl);
        $errorno = curl_errno($curl);
        if ($errorno) {
            return array('errorno' => false, 'errmsg' => $errorno);
        }
        curl_close($curl);
        return $res;
    }


}
